// DlgAdjustmentHistogram.cpp : implementation file
//

#include "stdafx.h"
#include "HubImage.h"
#include "DlgAdjustmentHistogram.h"


// DlgAdjustmentHistogram dialog

#define Timer_Cap_Interval      1000
#define Timer_Adjustment_LiveHistogram     0x1239


IMPLEMENT_DYNAMIC(DlgAdjustmentHistogram, CDialog)

DlgAdjustmentHistogram::DlgAdjustmentHistogram(CWnd* pParent /*=NULL*/)
: CDialog(DlgAdjustmentHistogram::IDD, pParent)
{
	m_bInit = FALSE;
	m_sMemDc.cx = 0;
	m_sMemDc.cy = 0;

	m_nMemDcHeight = 0;
}

DlgAdjustmentHistogram::~DlgAdjustmentHistogram()
{
	//KillTimer(Timer_Adjustment_LiveHistogram);
}


BOOL DlgAdjustmentHistogram::DestroyWindow()
{
	// TODO: Add your specialized code here and/or call the base class
	KillTimer(Timer_Adjustment_LiveHistogram);

	return CDialog::DestroyWindow();
}


void DlgAdjustmentHistogram::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(DlgAdjustmentHistogram, CDialog)
	ON_WM_SIZE()
	ON_WM_TIMER()
	ON_WM_PAINT()
END_MESSAGE_MAP()


// DlgAdjustmentHistogram message handlers

BOOL DlgAdjustmentHistogram::OnInitDialog()
{
	CDialog::OnInitDialog();

	// TODO:  Add extra initialization here
	m_nCheckCount = 5 ;
	if( m_nMemDcHeight <= 0 )
	{
		m_nMemDcHeight = 1;
	}
	m_sMemDc.cx = 0;
	m_sMemDc.cy = 0;
	
	m_nWidth = 0;

	m_bInit = TRUE;
	m_nMax  = 256;
	SetMarkValue( m_nMax );

	SetTimer(Timer_Adjustment_LiveHistogram,Timer_Cap_Interval,NULL);

	return TRUE;  // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}

#define BUT_WIDTH  30
#define BUT_HEIGHT 15

#define MEM_WIDTH 256

void DlgAdjustmentHistogram::OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);

	// TODO: Add your message handler code here
	if( !m_bInit )return;

	CRect rtClient,rt;
	GetClientRect(&rtClient);

	rt = rtClient;
	rt.bottom -= BUT_HEIGHT;

	GetDlgItem(IDC_STATIC_PIC)->MoveWindow( &rt );

	m_rMap = rtClient;
	m_rMap.bottom -= BUT_HEIGHT;
	m_nMemDcHeight = m_rMap.Height();
	if( m_nMemDcHeight <= 0 )
	{
		m_nMemDcHeight = 1;
	}

	m_nMemDcWidth = MEM_WIDTH;
	while( m_nMemDcWidth * 2 < m_rMap.Width() && m_nMemDcWidth < 1025 )
	{
		m_nMemDcWidth *= 2;
	}
	if( m_nMemDcWidth > 1024 )
	{
		m_nMemDcWidth = 1024;
	}
	
	//min
	rt.top    = rtClient.bottom - BUT_HEIGHT;
	rt.left   = 0;
	rt.right  = rt.left + BUT_WIDTH;
	rt.bottom = rtClient.bottom;

	GetDlgItem(IDC_STATIC_MIN)->MoveWindow( &rt );

	//left
	m_nWidth = rtClient.Width();
	int nWidth = m_nWidth;
	rt.top    = rtClient.bottom - BUT_HEIGHT;
	rt.left   = nWidth/10;
	rt.right  = rt.left + BUT_WIDTH;
	rt.bottom = rtClient.bottom;

	GetDlgItem(IDC_STATIC_LEFT)->MoveWindow( &rt );

	//right
	rt.top    = rtClient.bottom - BUT_HEIGHT;
	rt.right  = nWidth * 4 / 5;
	rt.left   = rt.right - BUT_WIDTH;
	rt.bottom = rtClient.bottom;

	GetDlgItem(IDC_STATIC_RIGHT)->MoveWindow( &rt );

	//max
	rt.top    = rtClient.bottom - BUT_HEIGHT;
	rt.right  = nWidth;
	rt.left   = rt.right - BUT_WIDTH;
	rt.bottom = rtClient.bottom;

	GetDlgItem(IDC_STATIC_MAX)->MoveWindow( &rt );
}

void DlgAdjustmentHistogram::SetMarkValue(int nMax)
{
	SetDlgItemInt(IDC_STATIC_MIN,0);
	SetDlgItemInt(IDC_STATIC_MAX,nMax);

	SetDlgItemInt(IDC_STATIC_LEFT, nMax/10);
	SetDlgItemInt(IDC_STATIC_RIGHT,nMax* 4 / 5);
}

void DlgAdjustmentHistogram::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: Add your message handler code here and/or call default

	if( Timer_Adjustment_LiveHistogram == nIDEvent )
	{
		void *pVoid = NULL;
		int nRet = g_HubCap.GetLineHistogramInfo(&pVoid);
		if( DD_ERR_SUCCESS == nRet && NULL != pVoid )
		{
			SetHistogramInfo((zkImgHistogram *)pVoid);
		} 
	}

	CDialog::OnTimer(nIDEvent);
}

#define RGB_NONEBACK RGB(51,204,204)
#define RGB_BACK     RGB(0,0,255)

#define RGB_LINE     RGB(255,255,255)


int DlgAdjustmentHistogram::SetHistogramInfo(zkImgHistogram *pImgHistogram)
{
	if( NULL == pImgHistogram ) return -1;

	CClientDC dc(this);

	if( m_nMemDcWidth > (int)pImgHistogram->dwBufSize )
	{
		m_nMemDcWidth = pImgHistogram->dwBufSize;
	}

	if( m_sMemDc.cx != m_nMemDcWidth )
	{
		if( m_sMemDc.cx != 0 || m_sMemDc.cy != 0 )
		{
			m_MemDC.DeleteDC();
			m_Bitmap.DeleteObject();
		}

		m_MemDC.CreateCompatibleDC(&dc);
		m_sMemDc.cx = m_nMemDcWidth;
		m_sMemDc.cy = m_nMemDcHeight;
		m_Bitmap.CreateCompatibleBitmap( &dc, m_sMemDc.cx, m_sMemDc.cy );
		m_MemDC.SelectObject( &m_Bitmap );		
	}

	if( m_nMax != pImgHistogram->dwBufSize )
	{
		m_nMax = pImgHistogram->dwBufSize;
		SetMarkValue( m_nMax );
	}

	int nGrayLevel = (1<<pImgHistogram->nBpp)-1;

	int    nPart  = m_nMax / m_nMemDcWidth;
	DWORD *pdwTmp = pImgHistogram->pdwPixels;

	int i=0,j=0;
	int nValue = 0;
	DWORD dwPixelCountPerPart[MEM_WIDTH*4];
	memset(dwPixelCountPerPart,0,sizeof(DWORD)*m_nMemDcWidth);

	for(i=0;i<m_nMemDcWidth;i++)
	{
		for(j=0;j<nPart;j++)
		{
			dwPixelCountPerPart[i] += (int)pdwTmp[i*nPart+j];
		}
	}

	RECT rt;
 	if(m_nCheckCount > 2)
	{
		DWORD nClr ;
		int nPerHeight = m_sMemDc.cy /(m_nCheckCount-1);
		for (i=0;i<m_nCheckCount-1;i++)
		{
			rt.top    = i*nPerHeight;
			if (i==m_nCheckCount-2)
			{
				rt.bottom = m_sMemDc.cy;
			}
			else
			{
				rt.bottom = rt.top + nPerHeight;
			}
			rt.left   = 0;   
			rt.right  = m_nMemDcWidth;
			nClr = RGB(80+i*25,101+i*25,156+i*25);
			m_MemDC.FillSolidRect( &rt, nClr );
		}
	}
	else
	{
		rt.top    = 0;
		rt.bottom = m_sMemDc.cy;
		rt.left   = 0;   
		rt.right  = m_nMemDcWidth;
		m_MemDC.FillSolidRect( &rt, RGB(80,101,156) );
	}

	//
	int nMaxHeight = nGrayLevel * nPart;

	if( nMaxHeight > 0 )
	{	
		HPEN hPen = CreatePen(PS_SOLID,1,RGB_LINE);
		HPEN hOldPen = (HPEN)SelectObject(m_MemDC.GetSafeHdc(),hPen);

		nValue = dwPixelCountPerPart[0];
		nValue *= m_nMemDcHeight;
		nValue /= nMaxHeight;
		m_MemDC.MoveTo( 0,m_nMemDcHeight - nValue );

		for(i=1;i<m_nMemDcWidth;i++)
		{
			nValue = dwPixelCountPerPart[i];
			nValue *= m_nMemDcHeight;
			nValue /= nMaxHeight;
			m_MemDC.LineTo( i,m_nMemDcHeight - nValue );
		}

		SelectObject(m_MemDC.GetSafeHdc(),hOldPen);
		DeleteObject(hPen); 
	}

	ShowSquareMap(&dc);

	return 0;
}

void DlgAdjustmentHistogram::ShowSquareMap(CDC *pDc)
{
	if( m_sMemDc.cx > 0 || m_sMemDc.cy > 0 )
	{
		pDc->StretchBlt(m_rMap.left,m_rMap.top,m_rMap.Width(),m_rMap.Height(),
			&m_MemDC,
			0,0,m_sMemDc.cx,m_sMemDc.cy,SRCCOPY);
	}
}

void DlgAdjustmentHistogram::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO: Add your message handler code here
	// Do not call CDialog::OnPaint() for painting messages
	ShowSquareMap(&dc);
}
